﻿using System;
using BSCMFF.Web.DomainService;
using System.ServiceModel.DomainServices.Client;
//using BSCMFF.Core.DataAccessLayer;

using System.Windows;
using System.Collections.Generic;
using System.Windows.Controls;
using StrategyMap.UserControls;
using Microsoft.Expression.Interactivity.Layout;
using System.Windows.Input;
using System.Windows.Shapes;
using System.Windows.Media;
using Microsoft.Expression.Controls;
using Microsoft.Expression.Media;
using StrategyMap.BusinessLayer;

namespace StrategyMap
{
    /// <summary>
    /// Strategy map.
    /// </summary>
    /// <remarks></remarks>
    public partial class Map : UserControl
    {
        /// <summary>
        /// Adds the nodes into strategy map.
        /// </summary>
        /// <remarks></remarks>
        private void AddNodesIntoStrategyMap()
        {
            List<Node1> newFinanceNodes = new List<Node1>();
            List<Node1> newCustomerNodes = new List<Node1>();
            List<Node1> newInternalNodes = new List<Node1>();
            List<Node1> newLearnNodes = new List<Node1>();

            foreach (Strategy_Node sn in loadOpNodes.Entities)
            {
                Node1 n = new Node1();
                n.StrategyName.Text = sn.Strategy_Node_ID.ToString();
                n.Name = sn.Strategy_Node_ID.ToString();

                if (sn.Positioned == false)
                {
                    n.Main.Fill = new SolidColorBrush(Colors.Transparent);

                    switch (sn.Strategic_Target.Perspective_FK)
                    {
                        case 1: newFinanceNodes.Add(n); break;
                        case 2: newCustomerNodes.Add(n); break;
                        case 3: newInternalNodes.Add(n); break;
                        case 4: newLearnNodes.Add(n); break;
                        default: break;
                    }
                }
                else
                {
                    Canvas.SetLeft(n, Convert.ToDouble(sn.CoordX));
                    Canvas.SetTop(n, Convert.ToDouble(sn.CoordY));

                    n.Radius = (int)sn.Bend;

                    Color cb;
                    if (sn.ColorBackground == null)
                    {
                        cb = Colors.Transparent;
                    }
                    else
                    {
                        cb = ColorTranslator.TranslateFromHex(sn.ColorBackground);
                    }
                    n.Main.Fill = new SolidColorBrush(cb);
                }
                MouseDragElementBehavior drag = new MouseDragElementBehavior();
                drag.ConstrainToParentBounds = true;
                //Interaction.GetBehaviors(n).Add(drag);
                n.StartDrawingArrowEvent += new MouseButtonEventHandler(Node_StartDrawingArrowEvent);
                //n.EventShowNodeDetails += new MouseButtonEventHandler(n_EventShowNodeDetails);
                n.MouseLeftButtonDown += new MouseButtonEventHandler(n_EventShowNodeDetails);

                LoadNodeDataContext(n, sn);

                LayoutRoot.Children.Add(n);
                nodes1.Add(n);
            }

            SetPositionForNodes(newFinanceNodes, newCustomerNodes, newInternalNodes, newLearnNodes);
        }

        /// <summary>
        /// Sets the position for nodes.
        /// </summary>
        /// <param name="newFinanceNodes">The new finance nodes.</param>
        /// <param name="newCustomerNodes">The new customer nodes.</param>
        /// <param name="newInternalNodes">The new internal nodes.</param>
        /// <param name="newLearnNodes">The new learn nodes.</param>
        /// <remarks></remarks>
        private void SetPositionForNodes(List<Node1> newFinanceNodes, List<Node1> newCustomerNodes, List<Node1> newInternalNodes, List<Node1> newLearnNodes)
        {
            const int nodeHeight = 60;
            const int nodeWidht = 140;
            const int yOffsetCustomer = 200;
            const int yOffsetInternal = 400;
            const int yOffsetLearn = 600;

            int countF = newFinanceNodes.Count;
            for (int i = 0; i < countF; ++i)
            {
                Canvas.SetTop(newFinanceNodes[i], (i % 3) * nodeHeight);
                Canvas.SetLeft(newFinanceNodes[i], (i / 3) * nodeWidht);
            }

            int countC = newCustomerNodes.Count;
            for (int i = 0; i < countC; ++i)
            {
                Canvas.SetTop(newCustomerNodes[i], ((i % 3) * nodeHeight) + yOffsetCustomer);
                Canvas.SetLeft(newCustomerNodes[i], (i / 3) * nodeWidht);
            }

            int countI = newInternalNodes.Count;
            for (int i = 0; i < countI; ++i)
            {
                Canvas.SetTop(newInternalNodes[i], ((i % 3) * nodeHeight) + yOffsetInternal);
                Canvas.SetLeft(newInternalNodes[i], (i / 3) * nodeWidht);
            }

            int countL = newLearnNodes.Count;
            for (int i = 0; i < countL; ++i)
            {
                Canvas.SetTop(newLearnNodes[i], ((i % 3) * nodeHeight) + yOffsetLearn);
                Canvas.SetLeft(newLearnNodes[i], (i / 3) * nodeWidht);
            }
        }

        /// <summary>
        /// Loads the node data context.
        /// </summary>
        /// <param name="n">The n.</param>
        /// <param name="sn">The sn.</param>
        /// <remarks></remarks>
        private void LoadNodeDataContext(Node1 n, Strategy_Node sn)
        {
            n.DataContext = sn.Strategic_Target.Name + "|" + sn.Strategic_Target.Description;
            n.StrategyName.Text = sn.Strategic_Target.Name;            
        }

        /// <summary>
        /// Handles the EventShowNodeDetails event of the n control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
        /// <remarks></remarks>
        void n_EventShowNodeDetails(object sender, MouseButtonEventArgs e)
        {
            if (EventNodeClicked != null)
            {
                EventNodeClicked(sender, new EventArgs());
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private Point pFrom;

        /// <summary>
        /// Creates the temporary arrow.
        /// </summary>
        /// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
        /// <remarks></remarks>
        private void CreateTemporaryArrow(MouseButtonEventArgs e)
        {
            pFrom = e.GetPosition(null);
                       
            la = new LineArrow();
            la.Stroke = new SolidColorBrush(Colors.Cyan);
            la.StrokeThickness = 3;
            la.BendAmount = 0;
            la.StartArrow = ArrowType.NoArrow;
            Canvas.SetLeft(la, pFrom.X);
            Canvas.SetTop(la, pFrom.Y);
            la.Width = 10;
            la.Height = 10;
            
            LayoutRoot.Children.Add(la);
        }

        /// <summary>
        /// Adds the target events for nodes.
        /// </summary>
        /// <remarks></remarks>
        private void AddTargetEventsForNodes()
        {
            List<int> nodesAlreadyTargeted = new List<int>();
            foreach (Strategy_Arrow sa in strategyContext.Strategy_Arrows)
            {
                if (sa.Strategy_Node_From_FK.ToString() == NodeDrawingArrowFrom.Name)
                {
                    nodesAlreadyTargeted.Add(sa.Strategy_Node_To_FK);
                }
            }

            foreach (Node1 n1 in nodes1)
            {
                bool dontAdd = false;
                foreach (int i in nodesAlreadyTargeted)
                {
                    if (n1.Name == i.ToString())
                    {
                        dontAdd = true;
                        break;
                    }
                }

                if (dontAdd == false && n1.Name != NodeDrawingArrowFrom.Name)
                {
                    n1.MouseEnter += new MouseEventHandler(Node_MouseEnter);
                    n1.MouseLeave += new MouseEventHandler(Node_MouseLeave);
                    n1.MouseLeftButtonUp += new MouseButtonEventHandler(Node_MouseLeftButtonUp);
                }
            }
        }
    }
}
